import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

// 定义错误类型枚举
enum ErrorType {
  videoLoadingFailed,
  controllerInitializationFailed,
  networkError,
  permissionDenied,
  unknownError,
}

// 错误信息类
class AppError {
  final ErrorType type;
  final String message;
  final String? details;
  final StackTrace? stackTrace;

  const AppError({
    required this.type,
    required this.message,
    this.details,
    this.stackTrace,
  });

  // 获取错误的友好显示消息
  String get userFriendlyMessage {
    switch (type) {
      case ErrorType.videoLoadingFailed:
        return '视频加载失败，请稍后重试';
      case ErrorType.controllerInitializationFailed:
        return '视频控制器初始化失败';
      case ErrorType.networkError:
        return '网络连接异常，请检查网络设置';
      case ErrorType.permissionDenied:
        return '权限不足，请检查应用权限设置';
      case ErrorType.unknownError:
      default:
        return '发生未知错误，请稍后重试';
    }
  }

  @override
  String toString() {
    return 'AppError(type: $type, message: $message, details: $details)';
  }
}

// 全局错误处理类
class ErrorHandler {
  // 单例实例
  static final ErrorHandler _instance = ErrorHandler._internal();

  // 工厂构造函数
  factory ErrorHandler() => _instance;

  // 内部构造函数
  ErrorHandler._internal();

  // 错误回调函数
  ValueChanged<AppError>? onError;

  // 初始化错误处理
  void initialize({ValueChanged<AppError>? onErrorCallback}) {
    onError = onErrorCallback;

    // 捕获Flutter框架错误
    FlutterError.onError = (FlutterErrorDetails details) {
      _handleFlutterError(details);
    };

    // 捕获异步错误
    PlatformDispatcher.instance.onError =
        (Object error, StackTrace stackTrace) {
      _handleAsyncError(error, stackTrace);
      return true;
    };
  }

  // 处理Flutter框架错误
  void _handleFlutterError(FlutterErrorDetails details) {
    final error = AppError(
      type: ErrorType.unknownError,
      message: 'Flutter框架错误',
      details: details.exceptionAsString(),
      stackTrace: details.stack,
    );
    _reportError(error);
  }

  // 处理异步错误
  void _handleAsyncError(Object error, StackTrace stackTrace) {
    final appError = AppError(
      type: ErrorType.unknownError,
      message: error.toString(),
      stackTrace: stackTrace,
    );
    _reportError(appError);
  }

  // 报告应用特定错误
  void reportError(AppError error) {
    _reportError(error);
  }

  // 内部错误报告方法
  void _reportError(AppError error) {
    // 在控制台打印错误信息
    if (kDebugMode) {
      print('\n=== 应用错误报告 ===');
      print('类型: ${error.type}');
      print('消息: ${error.message}');
      if (error.details != null) {
        print('详情: ${error.details}');
      }
      if (error.stackTrace != null) {
        print('堆栈跟踪: ${error.stackTrace}');
      }
      print('====================\n');
    }

    // 触发错误回调
    if (onError != null) {
      onError!(error);
    }
  }

  // 处理视频相关错误
  void handleVideoError(String message, {String? details}) {
    final error = AppError(
      type: ErrorType.videoLoadingFailed,
      message: message,
      details: details,
    );
    reportError(error);
  }

  // 处理控制器初始化错误
  void handleControllerError(String message, {StackTrace? stackTrace}) {
    final error = AppError(
      type: ErrorType.controllerInitializationFailed,
      message: message,
      stackTrace: stackTrace,
    );
    reportError(error);
  }

  // 显示错误对话框
  void showErrorDialog(BuildContext context, AppError error) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('错误'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(error.userFriendlyMessage),
            if (kDebugMode && error.details != null)
              Padding(
                padding: const EdgeInsets.only(top: 8),
                child: Text(
                  '详细信息: ${error.details}',
                  style: TextStyle(color: Colors.grey[600], fontSize: 12),
                ),
              ),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('确定'),
          ),
        ],
      ),
    );
  }
}
